home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
bgi_font.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-16
|
6KB
|
228 lines
#include "bgi_font.h"
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <STDDEF.H>
#include <alloc.h>
#define MAXFILESIZE 16000
char* BGI_Font::buffer = NULL;
BGI_Font::BGI_Font(char* fileName)
{
h_just = 0; // LEFT_TEXT
v_just = 0; // BOTTOM_TEXT
if(buffer != NULL)
{
delete buffer;
buffer = NULL;
}
multx = multy = divx = divy = 1;
polypoints = NULL;
if(fileName == NULL)
return;
load(fileName);
polypoints = new int[256]; // Default number of points in closed
};
//////////////
BGI_Font::~BGI_Font()
{
delete[] buffer;
buffer = NULL;
delete polypoints;
}
////////////////
void BGI_Font::load(char* fileName)
{
int handle;
if((handle = open(fileName, O_RDONLY | O_BINARY)) == -1)
{
kh_error_code = KH_FILE_ERROR;
return;
}
if(buffer == NULL)
if((buffer = new char[MAXFILESIZE]) == NULL)
{
close(handle);
kh_error_code = KH_MEMORY_ERROR;
return;
}
if(read(handle, buffer, MAXFILESIZE) == -1)
{
delete buffer;
close(handle);
kh_error_code = KH_FILE_ERROR;
return;
}
close(handle);
int pos = 0;
while(buffer[pos] != 26) // All info fields are skipped
pos++;
pos++;
// BGI_Font Font Info
HeaderSize = ((int*)(buffer + pos))[0]; // ...
pos += sizeof(int);
pos += 4; // char* FontName;
FontSize = ((int*)(buffer + pos))[0]; // ...
pos += sizeof(int); // int FontSize, Font without header
pos++; // char FontVersion, > 0
pos++; // char FontModification;
pos += sizeof(int); // int BGI_FontInfo, BGI_Font version
// BGI_Font Font descriptor
while(buffer[pos] != '+')
pos++; // char DscSignature, Always '+'
pos++;
SymbolsInFont = buffer[pos++]; // Usually start from ' '
pos++; pos++;
FirstSymbol = buffer[pos++]; // Usually start from ' '
StrokesOffset = ((int*)(buffer + pos))[0]; // Characters descriptions offset
pos += sizeof(int);
FillFlag = buffer[pos++]; // Fill or not, default 0
CapitalHeight = buffer[pos++]; // ...
BaseLine = buffer[pos++]; // Usually 0
Descender = buffer[pos++]; // for y, g and other
pos += 5; // char Stub02[5], Not used and set to 0
// BGI_Font Tables
OffsetTable = (int*)(buffer + pos); // Offsets of symbols descriptions
pos += SymbolsInFont * 2;
WidthTable = (buffer + pos);
pos += SymbolsInFont;
vectors = buffer + pos;
}
////////////////
int BGI_Font::draw_char(int x, int y, uchar c, int dir)
{
if(c >= SymbolsInFont + FirstSymbol || c < FirstSymbol) // ERROR !!!
{ // Out of inter-
kh_error_code = KH_BGI_ERROR; // val
return 0;
}
char* pos = vectors + OffsetTable[c - FirstSymbol]; // Find description
int numpoint = 0;
moveto(x, y);
int xpos; int sign; int ypos;
for(int i = 0; (pos [i] & 128); i += 2) // While end of char
{ // description
if(!dir)
{
xpos = x + (pos [i] & 127) * multx / divx; // Calculate coords.
sign = pos[i + 1] & 64 ? 1 : 0;
ypos = y + (sign * 64 - (pos [i + 1] & 63)) * multy / divy;
}
else
{
sign = pos[i + 1] & 64 ? 1 : 0;
xpos = x + (sign * 64 - (pos [i + 1] & 63)) * multx / divx; // Calculate coords.
ypos = y - (pos [i] & 127) * multy / divy;
}
if((pos [i + 1] & 128) && (pos [i] & 128)) // Drawing via moveto
{ // and lineto
if(FillFlag) // For filled fonts lineto
{ // draws filled part of
polypoints[numpoint++] = xpos; // character, like upper
polypoints[numpoint++] = ypos; // '.' in ':'
} // Moveto begin next part
else // of char.
lineto(xpos, ypos);
}
else
{
if(FillFlag && numpoint)
{
numpoint = numpoint / 2;
fillpoly(numpoint, polypoints);
numpoint = 0;
}
else
moveto(xpos, ypos);
}
}
if(FillFlag && numpoint) // If next part of char was not
{ // shown.
numpoint = numpoint / 2;
fillpoly(numpoint, polypoints);
numpoint = 0;
}
return (int)((long)WidthTable[c - FirstSymbol] * multx / divx);
}
////////////////
int BGI_Font::outtextxy(int x, int y, uchar far* str, int dir)
{
int len = 0;
int i = 0;
int w;
int h = v_just * getheight() / 2;
while(str[i])
switch(h_just)
{
case 1: w = gettextwidth(str);
if(!dir)
len += draw_char(x - w/2 + len, y + h, str[i++]);
else
len += draw_char(x + h, y + w/2 - len, str[i++], dir);
break;
case 2: w = gettextwidth(str);
if(!dir)
len += draw_char(x - w + len, y + h, str[i++]);
else
len += draw_char(x + h, y + w - len, str[i++], dir);
break;
case 0:
default:
if(!dir)
len += draw_char(x + len, y + h, str[i++]);
else
len += draw_char(x + h, y - len, str[i++], dir);
break;
}
return len;
}
////////////////////
int BGI_Font::gettextwidth(uchar far* str)
{
int len = 0;
int i = 0;
while(str[i])
{
len += WidthTable[str[i] - FirstSymbol];
i++;
}
return len;
}
/*
// Demo for BGI, DOS, Draw nothing, using ABS_GRAF functions.
// See BGIPAINT for the working example.
void main()
{
int gdriver = DETECT, gmode;
initgraph(&gdriver, &gmode, "");
BGI_Font bgi("bold.chr");
setcolor(LIGHTGREEN);
bgi.draw_char(100, 200, 'J', 1);
bgi.draw_char(100, 200, 'J', 0);
for(int c = 0; c < 255; c++)
{
setfillstyle(SOLID_FILL, RED);
bar(0,0,getmaxx(),getmaxy());
setfillstyle(SOLID_FILL, BLUE);
bgi.setusercharsize(1,1,1,1);
bgi.draw_char(50, 300, c);
bgi.setusercharsize(2,1,2,1);
bgi.draw_char(150, 300, c);
bgi.setusercharsize(3,1,5,1);
bgi.draw_char(300, 300, c);
bgi.setusercharsize(5,1,5,2);
bgi.draw_char(500, 300, c);
}
closegraph();
}
*/